package com.cly.item.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cly.common.entity.item.dto.ScheduleItemDTO;
import com.cly.common.entity.item.po.TimingItem;
import com.cly.common.entity.result.Result;
import com.cly.common.exception.CommonException;
import com.cly.item.mapper.TimingItemMapper;
import com.cly.item.service.TimingItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class TimingItemServiceImpl extends ServiceImpl<TimingItemMapper,TimingItem> implements TimingItemService {
    private final ThreadPoolTaskScheduler threadPoolTaskScheduler;
    private final TimingItemMapper timeMapper;

    /**
     * 指定某个时间后发布商品
     *
     * @param scheduleItemDTO
     */
    @Override
    public Result scheduleAddItem(ScheduleItemDTO scheduleItemDTO) {
        // 提前校验DTO
        if (scheduleItemDTO == null || scheduleItemDTO.getExecutionTime() == null) {
            throw new CommonException("参数不能为空");
        }
        TimingItem timingItem = BeanUtil.copyProperties(scheduleItemDTO, TimingItem.class);
        timingItem.setStatus(0);
        // 先保存到数据库，设置为未发布
        this.save(timingItem);
        try {
            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();
            // 计算任务执行的时间距离现在是多少
            long delay = Duration.between(now, scheduleItemDTO.getExecutionTime()).toMillis();
            if (delay > 0) {
                // 执行计划
                threadPoolTaskScheduler.schedule(() -> {
                    // 执行任务逻辑
                    // 更新状态为已发布
                    timingItem.setStatus(1);
                    this.updateById(timingItem);
                    // 执行延迟删除商品
                    this.scheduleDeleteItemByStatus(timingItem.getId(), scheduleItemDTO.getEndTime());
                }, Instant.from(scheduleItemDTO.getExecutionTime()));
                return Result.success();
            } else {
                throw new CommonException("时间不能早于当前时间");
            }
        } catch (Exception e) {
            throw new CommonException("定时发布商品失败", e);
        }
    }

    /**
     * 指定某个时间后逻辑删除商品
     * @param scheduleItemId
     * @param endTime
     */
    public void scheduleDeleteItemByStatus(Long scheduleItemId, LocalDateTime endTime){
        try {
            LocalDateTime now = LocalDateTime.now();
            long delay = Duration.between(now, endTime).toMillis();
            if(delay > 0){
                threadPoolTaskScheduler.schedule(() -> {
                    this.lambdaUpdate().eq(TimingItem::getId, scheduleItemId).set(TimingItem::getStatus, 3);
                },  Instant.from(endTime));
            }else{
                throw new CommonException("时间不能早于当前时间");
            }
        } catch (Exception e) {
            throw new CommonException("逻辑删除限时商品失败",e);
        }
    }

    /**
     *  删除status为3的商品
     */
    @Scheduled( cron = "0 0 6 * * ?",zone = "Asia/Shanghai")
    public void  scheduleDeleteItem(){
        try {
            this.lambdaUpdate()
                    .eq(TimingItem::getStatus, 3)  // 先确保只处理已逻辑删除的商品
                    .remove();  // 建议使用remove()进行物理删除而非setStatus
        } catch (Exception e) {
            throw new CommonException("删除限时商品失败",e);
        }
    }
}
